Amazon LinuxへのsshをGoogle Authenticatorを用いて二段階認証にしてみた
はじめに
こんにちは植木和樹@上越妙高オフィスです。今日はAmazon Linuxへのsshログイン時におけるセキュリティ強化のお話です。
AWS運用チェックリストではOSにログインする際のユーザーは共有せず、個人ごとにOSアカウントを作成することが推奨されています。
個人ごとにOSアカウントを作成すれば、いつ誰がそのサーバーにログインしたのか分かるので不正な操作が行われた際のトレースに役立ちます。
しかし仮にパソコンが盗まれる等で秘密鍵が盗まれてしまった場合を想定し、さらにもう一段階、その人のみが持っているものを用いなければサーバーにログインできない仕掛けを作ってみます。これを2段階認証といいます。今回は 1.個人のssh鍵ファイル + 2.スマホに表示されるワンタイムパスワード、の2つで設定してみました。
Google Authenticatorのインストール
ワンタイムパスワードによる認証にはGoogle Authenticatorを利用しました。
サーバーにはAmazon Linux (2015.09)を使用しました。AWS公式リポジトリにRPMで提供されていますので、yumコマンドでインストールが可能です。ここではGoogle AuthenticatorにてQRコードによる設定を有効にしたいのでqrencodeライブラリも一緒に入れています。
sudo yum install google-authenticator qrencode-libs -y
クライアントはGoogle Authenticatorアプリでも良いですが、Authyや1Password (Pro)などワンタイムパスワードの対応しているアプリでもOKです。
サーバー側の設定
サーバー側の設定は大きく3箇所を修正します。
- sshd の設定ファイル(/etc/ssh/sshd_config)
- sshd のPAM設定ファイル(/etc/pam.d/sshd)
- ログイン時のbash profileファイル(/etc/profile.d/google-authenticator)
sshd の設定ファイル
sshd_config はChallengeResponseAuthenticationが初期設定でnoになっていますが、これをyesに変更します。これによりssh鍵ファイル認証だけでなく、キーボードからの入力を用いた認証も可能になります。
/etc/ssh/sshd_config (修正箇所)
$ grep \ -e ^PasswordAuthentication \ -e ^ChallengeResponseAuthentication \ -e ^UsePAM \ /etc/ssh/sshd_config PasswordAuthentication no ChallengeResponseAuthentication yes UsePAM yes
さらに下記の設定を追記します。もしものためにec2-userは鍵認証のみでのログインを可能にし、それ以外のユーザーでのみ鍵認証+ワンタイムパスワード認証を有効にしておきます。
/etc/ssh/sshd_config (追記箇所)
AuthenticationMethods publickey,keyboard-interactive Match User ec2-user AuthenticationMethods publickey PubkeyAuthentication yes PasswordAuthentication no
設定を修正したら sshd を再起動しましょう。
$ sudo service sshd restart
sshd のPAM設定ファイル
前の手順で、sshのパスワードによる認証が有効になりました。次にPAMの設定を修正し、sshログイン認証時にGoogle Authenticatorが使われるようにします。
まずは下記の内容で /etc/pam.d に新しい設定ファイルを作成します。
/etc/pam.d/google-auth
#%PAM-1.0 auth required pam_env.so auth sufficient pam_google_authenticator.so nullok auth requisite pam_succeed_if.so uid >= 500 quiet auth required pam_deny.so
設定は上から順に評価されていきます。
- 2行目は環境変数を読み込むおまじない
- 3行目でGoogle Authenticatorを有効にしています。soファイルは /lib64/security/ から読み込まれます。nullok オプションをしているため初回ログインでGoogle Authenticatorを初期化(後述)していない場合はここでの認証処理はパスされます。
- 3行目は sufficient を指定しているのでGoogle Authenticatorによる認証がOKならログインが可能になります。
- 4行目はログインユーザーの uid が500以上(一般ユーザー)であることを強制してしています。requisiteしていているのでuidが500未満の人はここでログインが拒否されます。(なおこの行に到達するのは4行目で説明した初回ログイン時だけです)
- 認証がNGなら5行目でログインが拒否されます。
次にsshdのPAM設定を修正します。初期設定でpassword-authが有効になっているのでこれをコメントアウトし、先ほど作成した google-auth と入れ替えましょう。
/etc/pam.d/sshd
#%PAM-1.0 auth required pam_sepermit.so #auth substack password-auth auth substack google-auth auth include postlogin account required pam_nologin.so account include password-auth password include password-auth # pam_selinux.so close should be the first session rule session required pam_selinux.so close session required pam_loginuid.so # pam_selinux.so open should only be followed by sessions to be executed in the user context session required pam_selinux.so open env_params session optional pam_keyinit.so force revoke session include password-auth session include postlogin
ログイン時のbash profileファイル
ユーザーがログインした時に強制的なGoogle Authenticatorの初期化を有効にするため、/etc/profile.d に下記内容でファイルを作成します。
/etc/profile.d/google-authenticator.sh
#!/bin/sh if [ "$USER" != "root" -a "$USER" != "ec2-user" ]; then if [ ! -f "$HOME/.google_authenticator" ]; then # 2018/03/12 いただいたコメントを反映し、初期化処理の前後のみトラップするよう修正しました trap 'exit' SIGINT echo "google-authenticator の初期設定を行います" /usr/bin/google-authenticator -t -d -W -u -f trap -- SIGINT fi fi
INTシグナルをトラップして exit しているため、認証途中でCtrl+Cすると強制ログアウトします。
なお google-authenticator コマンドに渡しているオプションは次の意味があります。
- -t
- 時刻ベースのワンタイムパスワードを生成する。
- -d
- 一度利用したワンタイムパスワードの再利用を禁止する。時刻ベースのため30秒経過しないと新しいワンタイムパスワードが生成されません。これにより連続して同一サーバーへログインはできなくなります。
- -W
- 認証コードを有効とする時刻のズレを最小にする。サーバーとクライアントの時刻ズレは90秒までなら許容されます。
- -u
- 一定時間内のログイン回数制限を行わない。有効にした場合の初期設定は30秒間に3回までに制限されます。
- -f
- 確認なしでユーザーホームディレクトリの設定ファイルを上書きする。
コマンドラインオプションを付けなければ対話的に設定ができますが、今回はこちらで指定することにしました。
ログインしてみる
ec2-userのログインユーザーを作成して、ssh鍵認証の設定をしたらログインしてみます。
でかっ!!
qrencodeライブラリでQRコードが表示されます。これをスマホに入れたGoogle Authenticatorアプリ(またはAuthyや1Password)のカメラで撮って設定しましょう。 設定が終わったら一旦ログアウトします。再度ログインすると今度はワンタイムパスワード認証が有効になります。
いいですね!
まとめ
Google Authenticatorを利用して二段階認証をAmazon Linuxに設定してみました。 PCIDSSでは、カード情報を取り扱うサーバーへのログイン時に二段階認証を要求します。Amazon Linuxなら上記の通り認証ライブラリがyumで提供されていますし、ワンタイムパスワードもAWSマネージメントにMFAを設定していることで慣れていると思いますので簡単に導入できそうですね。
またすべてのサーバーを二段階認証に対応させるのではなく、踏み台サーバーのみに設定して管理を楽にする方法も考えられると思います。もちろん各サーバーは踏み台サーバー経由のみsshログインを許可するようセキュリティグループで制限することをお忘れなく。
それではサーバーを安全に保って、快適なAmazon Linuxライフを!